package com.googlecode.perfectable.visuable.parse;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.googlecode.perfectable.visuable.parse.DocumentConstants.XHTML_NAMESPACE;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.googlecode.perfectable.eventable.routing.Sink;
import com.googlecode.perfectable.eventable.routing.Source;
import com.googlecode.perfectable.prosperable.message.ClientMessage;
import com.googlecode.perfectable.prosperable.message.ServerMessage;
import com.googlecode.perfectable.visuable.configuration.Configurator;
import com.googlecode.perfectable.visuable.visual.Visual;

public class DocumentConverter {
	private final VisualRegistry registry = new MapVisualRegistry();
	private final VisualConverter visualConverter;
	private final StandardConfigurationBuilder configurationBuilder;

	public DocumentConverter(Configurator configurator, Source<ClientMessage> source, Sink<ServerMessage> sink) {
		this.configurationBuilder = new StandardConfigurationBuilder(configurator, sink);
		this.visualConverter = new StandardVisualConverter(this.registry, this.configurationBuilder, source); // MARK
																																																								// configurable
	}

	public Visual processDocument(Document document) {
		Element documentElement = document.getDocumentElement();
		Visual rootVisual = this.processElement(documentElement);
		return rootVisual;
	}

	private Visual processElement(Element documentElement) {
		checkNotNull(documentElement);
		String uri = documentElement.getNamespaceURI();
		checkArgument(XHTML_NAMESPACE.equals(uri));
		Visual visual = this.visualConverter.convertVisual(documentElement);
		this.configurationBuilder.performInjections(this.registry);
		return visual;
	}

}
